package com.tbit.uqbike.client.ordertrace.validation;

import cn.hutool.core.collection.CollectionUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.schema.*;
import com.tbit.uqbike.client.ordertrace.TransitionValidator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Set;

/**
 * JsonSchema校验器
 *
 * @author <a href="mailto:chen.chaoxiong@tbit.com.cn">ChenChaoXiong</a>
 * @since 2024/7/17
 */
@Slf4j
public class JsonSchemaTransitionValidator implements TransitionValidator {

    private String rule;
    private ObjectMapper objectMapper;

    public JsonSchemaTransitionValidator(String rule) {
        this.rule = rule;
        this.objectMapper = new ObjectMapper();
    }

    /**
     * 校验状态转换
     *
     * @param data 需要校验的JSON数据
     * @return 是否校验通过
     */
    @Override
    public boolean validateTransition(String data) {
        if (StringUtils.isBlank(rule)) {
            return true;
        }

        try {
            // 先检查JSON字符串是否符合JSON语法规范
            objectMapper.readTree(data);

            JsonSchemaFactory schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7);
            JsonSchema schema = schemaFactory.getSchema(rule);
            JsonNode jsonNode = objectMapper.readTree(data);
            Set<ValidationMessage> validationErrors = schema.validate(jsonNode);
            if (CollectionUtil.isNotEmpty(validationErrors)) {
                log.error("JSON data validation failed: {}", validationErrors);
                return false; // 校验未通过
            }
            return true; // 校验通过
        } catch (JsonProcessingException e) {
            log.error("Invalid JSON data: {}", e.getMessage());
            return false; // JSON数据不符合语法规范
        } catch (JsonSchemaException e) {
            log.error("JSON data validation failed: {}, detail: {}", e.getMessage(),e.getValidationMessages());
            return false; // 校验未通过
        }  catch (Exception e) {
            log.error("validation failed: {}", e.getMessage());
            return false; // 发生其他异常,也视为校验未通过
        }
    }
}
